package common;

import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.PrintWriter;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import math.AdjEntropy;
import math.Entropy;
import math.common.MathCommon;
import math.probability.ExpDistribution;
import math.probability.NormalDistribution;
import math.probability.ProbDistribution;

public class EIVEntropyApproach {
	
	public EIVEntropyApproach() {
		
	}
	
	public void calc () {
//		ProbDistribution distX = new ExpDistribution(1.0);
		ProbDistribution distX = new NormalDistribution(3.0,0.8); 
		ProbDistribution distEps = new NormalDistribution(0.0,0.3);
		ProbDistribution distXi = new NormalDistribution(0.0,0.1);
		Double b0 = 0.5;
		Double b1 = 1.0;
		int n = 5000;
		StructuralModel model = new StructuralModel(n,distX, distXi, distEps, b0, b1);
		Double bSet[] = {0.5, 0.6, 0.7, 0.8, 0.9, 1.0, 1.1, 1.2, 1.3, 1.4, 1.5};

		Map<Double, Double> data = MathCommon.Normalize(model.getData());
		
		Map<Double, List<Double>> smpls = new HashMap();
		Map<Double, Double> entropy = new HashMap();
		Entropy entropyCalc = new AdjEntropy();
		System.out.println("Coeff b;Entropy");
		for (Double b : bSet) {
			List<Double> smpl = new ArrayList<Double>();
			for (Double u : data.keySet()) {
				smpl.add(data.get(u)-b*u);
			}
			Double mean = MathCommon.getMean(smpl);
			Double stdDev = Math.sqrt(MathCommon.getVar(smpl));
			List<Double> stdSmpl = new ArrayList<Double>();
			
			for (Double val : smpl) {
				stdSmpl.add((val-mean)/stdDev);
			}
			
			smpls.put(b, stdSmpl);
			Double e = entropyCalc.getSmplEntropy(stdSmpl);
			entropy.put(b, e);
			System.out.println(b + ";" + e);
		}
	}
	
	public void calcE () {
//		ProbDistribution distX = new ExpDistribution(1.0);
		ProbDistribution distX = new NormalDistribution(3.0,0.8); 
		ProbDistribution distEps = new NormalDistribution(0.0,0.3);
		ProbDistribution distXi = new NormalDistribution(0.0,0.1);
		Double b0 = 0.0;
		Double b1 = 1.0;
		int n = 500;
		StructuralModel model = new StructuralModel(n,distX, distXi, distEps, b0, b1);
		Double bSet[] = {0.5, 0.6, 0.7, 0.8, 0.9, 1.0, 1.1, 1.2, 1.3, 1.4, 1.5};

		Map<Double, Double> data = MathCommon.Normalize(model.getData());
		
		model.printData("StrModel_data.csv");
		

		
		
				
		System.out.println("Coeff b;Entropy");
		for (Double b : bSet) {
			List<Double> smpl = new ArrayList<Double>();
			for (Double u : data.keySet()) {
				smpl.add(data.get(u)-b*u);
			}

			System.out.println(b + ";" + Math.abs(MathCommon.getMean(smpl)));
		}
	}
	
	
	
	public static void main(String[] args) {
		EIVEntropyApproach app = new EIVEntropyApproach();
		app.calcE();
	}

}
